package com.dhp.campus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dhp.campus.Common.ErrorCode;
import com.dhp.campus.Constant.ApplicationConstant;
import com.dhp.campus.Enum.friendsStatus;
import com.dhp.campus.Exception.exception;
import com.dhp.campus.domain.Friends;
import com.dhp.campus.domain.User;
import com.dhp.campus.domain.vo.FriendsRecordsVO;
import com.dhp.campus.mapper.FriendsMapper;
import com.dhp.campus.service.FriendsService;
import com.dhp.campus.service.UserService;
import com.google.gson.Gson;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

import static com.dhp.campus.utils.StringUtils.stringJsonListToLongSet;


/**
* @author Dhp
* @description 针对表【friends(好友申请管理表)】的数据库操作Service实现
* @createDate 2024-03-12 15:17:19
*/
@Service
public class FriendsServiceImpl extends ServiceImpl<FriendsMapper, Friends>
    implements FriendsService {


    @Autowired
    private UserService userService;

    @Override
    public List<FriendsRecordsVO> getRecords(HttpServletRequest request) {
        //获取当前登录用户
        User loginUser  = userService.getCurrentUser(request);
        if (loginUser == null){
            throw new exception(ErrorCode.NOT_LOGIN);
        }
        Long userId = loginUser.getId();

        //从表中获取所有申请，判断状态
        QueryWrapper<Friends> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("receive_id" , userId);
        setExpire(queryWrapper);
        return toFriendsVo(queryWrapper);
    }

    @Override
    public Boolean addFriends(Long userId , HttpServletRequest request) {
        User loginUser = userService.getCurrentUser(request);
        if (loginUser == null){
            throw new exception(ErrorCode.NOT_LOGIN);
        }
        Long loginId = loginUser.getId();

        //查看当前用户是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id" , userId);
        long count = userService.count(queryWrapper);
        if (count == 0){
            throw new exception(ErrorCode.BUSINESS_ERROR , "当前用户不存在");
        }

        //不能添加自己
        if (userId.equals(loginId)){
            throw new exception(ErrorCode.BUSINESS_ERROR , "不能添加自己");
        }

        //防止重复添加 逻辑改为搜寻全部的好友看是否包含
        String userIds = loginUser.getUserIds();
        Set<Long> friends = stringJsonListToLongSet(userIds);
        if (friends.contains(userId)){
            throw new exception(ErrorCode.BUSINESS_ERROR , "不能重复添加");
        }
        if(friends.size() > ApplicationConstant.MAX_NUM){
            throw new exception(ErrorCode.BUSINESS_ERROR , "好友数量已达上线");
        }
//        QueryWrapper<Friends> friendsQueryWrapper = new QueryWrapper<>();
//        friendsQueryWrapper.eq("receive_id" , userId);
//        friendsQueryWrapper.eq("from_id" , loginId);
//        Friends one = this.getOne(friendsQueryWrapper);
//        if (one != null){
//            throw new exception(ErrorCode.BUSINESS_ERROR , "不能重复添加");
//        }

        //发送请求
        Friends addRequest = new Friends();
        addRequest.setFromId(loginId);
        addRequest.setReceiveId(userId);
        return this.save(addRequest);
    }




    public List<FriendsRecordsVO> getMyRecord(HttpServletRequest request){
        User loginUser = userService.getCurrentUser(request);
        if (loginUser == null){
            throw new exception(ErrorCode.NOT_LOGIN);
        }

        QueryWrapper<Friends> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("from_id" , loginUser.getId());
        return toFriendsVo(queryWrapper);
    }


    @Override
    @Transactional
    public Boolean agreeApply(Long id, HttpServletRequest request) {
        //获取的是safetyuser
        User loginUser = userService.getCurrentUser(request);
        if (loginUser == null){
            throw new exception(ErrorCode.NOT_LOGIN);
        }

        //更新申请表状态为已读且同意
        Long userId = loginUser.getId();
        QueryWrapper<Friends> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("from_id" , id);
        queryWrapper.eq("receive_id" , userId);
        queryWrapper.eq("is_read" , 0);

        //查询请求的状态
        Friends originalApply = this.getOne(queryWrapper);
        if (originalApply.getStatus().equals(friendsStatus.AGREED.getStatus())){
            throw new exception(ErrorCode.BUSINESS_ERROR , "你们已经是好友了");
        }

        Friends newFriends = new Friends();
        newFriends.setIsRead(1);
        newFriends.setStatus(friendsStatus.AGREED.getStatus());
        newFriends.setUpdateTime(new Date());
        boolean update = this.update(newFriends, queryWrapper);

        //在双方表中的ids加入该对方id
        User applyUser = userService.getById(id);
        User newLoginUser = agree(loginUser, id);
        User newApplyUser = agree(applyUser , userId);
        boolean a = userService.updateById(newLoginUser);
        boolean b = userService.updateById(newApplyUser);

        return update && b && a;
    }

    @Override
    @Transactional
    public Boolean refuseApply(Long id, HttpServletRequest request) {
        User loginUser = userService.getCurrentUser(request);
        if (loginUser == null){
            throw new exception(ErrorCode.NOT_LOGIN);
        }
        Long userId = loginUser.getId();

        //将申请表中的状态改为已读，拒绝
        QueryWrapper<Friends> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("from_id" , id).eq("receive_id" , userId);

        //查询请求的状态
        Friends originalApply = this.getOne(queryWrapper);
        if (originalApply.getStatus().equals(friendsStatus.REFUSED.getStatus())){
            throw new exception(ErrorCode.BUSINESS_ERROR , "你已经拒绝了该请求");
        }


        Friends newApply = new Friends();
        newApply.setIsRead(1);
        newApply.setStatus(friendsStatus.REFUSED.getStatus());
        newApply.setUpdateTime(new Date());
        return this.update(newApply, queryWrapper);
    }

    @Override
    @Transactional
    public Boolean deleteFriend(Long id, HttpServletRequest request) {
        User loginUser = userService.getCurrentUser(request);
        if (loginUser == null){
            throw new exception(ErrorCode.NOT_LOGIN);
        }
        Long userId = loginUser.getId();
        //查询另一方的信息
        User friend = userService.getById(id);

        //已删除或不是好友不能删除
        String userIds = loginUser.getUserIds();
        Set<Long> friends = stringJsonListToLongSet(userIds);
        Set<Long> another = stringJsonListToLongSet(friend.getUserIds());
        if (!friends.contains(id) && !another.contains(userId)){
            throw new exception(ErrorCode.BUSINESS_ERROR , "他不是您的好友");
        }



        boolean remove = friends.remove(id);
        boolean remove2 = another.remove(userId);
        Gson gson = new Gson();
        String Json = gson.toJson(friends);
        String Json2 = gson.toJson(another);
        if (remove && remove2) {
            //更新用户信息
            loginUser.setUserIds(Json);
            friend.setUserIds(Json2);
            boolean update = userService.updateById(loginUser);
            boolean update2 = userService.updateById(friend);
            return update && update2;
        }
        throw new exception(ErrorCode.BUSINESS_ERROR , "删除失败");
    }

    private List<FriendsRecordsVO> toFriendsVo(QueryWrapper<Friends> queryWrapper) {
        List<Friends> friendsList = this.list(queryWrapper);
        //按照时间顺序，最前为最新
        Collections.reverse(friendsList);
        return friendsList.stream().map(friend -> {
            FriendsRecordsVO friendsRecordVO = new FriendsRecordsVO();
            BeanUtils.copyProperties(friend, friendsRecordVO);
            User user = userService.getById(friend.getFromId());
            friendsRecordVO.setApplyUser(userService.getSafetyUser(user));
            return friendsRecordVO;
        }).collect(Collectors.toList());
    }

    private boolean setExpire(QueryWrapper<Friends> queryWrapper){
        List<Friends> friendsList = this.list(queryWrapper);
        List<Friends> expireApply = new ArrayList<>();
        Date now = new Date();

        //获取过期请求
        for (Friends friends : friendsList) {
            long time = now.getTime() - friends.getCreateTime().getTime();
            time = time / (24 * 60 * 60 * 1000);
            if (time > ApplicationConstant.ALIVE){
                friends.setStatus(friendsStatus.EXPIRED.getStatus());
                expireApply.add(friends);
            }
        }

        //更新数据库
        return this.updateBatchById(expireApply);

    }

    private User agree(User receive , Long fromId){
        String json = receive.getUserIds();
        Set<Long> ids = stringJsonListToLongSet(json);
        ids.add(fromId);
        Gson gson = new Gson();
        String s = gson.toJson(ids);
        receive.setUserIds(s);

        return receive;
    }

}




